<?php

	/**
	 * <version greek="beta" major="1" minor="0">Cochin Splash Hen</version>
	 * <author email="njones@art-k-tec.com">Nika Jones</author>
	 * <copyright start="2007">Art-k-tec Systems, LLC</copyright>
	 * <license type="Apache2.0" href="http://www.opensource.org/licenses/apache2.0.php">Apache License, Version 2.0</license>
	 * <summary>
	 *    Provides a UTF-8 multi-byte safe method of dealing with strings
	 *    So you really don't need to worry about the encoding
	 * </summary> 
	*/
	class bString {
		const ENCODING ='UTF-8';
		const REVERSE = '00000000001';
		const REGULAR_EXPRESSION = '2';
		const STRING_REPLACE = '4';
		
		private $aMatch;
		private $sString;
		
		///<summary>
		///   The constructor
		///</summary>
		///<param type="string" name="sString" optional="true">
		///   The string to use in bString converted to the correct encoding
		///</param>
		///<returns type="bString" />
		public function __construct($sString ='') {
			
			// Check to make sure that it is UTF-8 encoded
			$this->sString =mb_convert_encoding($sString, self::ENCODING);
			
			return $this;
		}
		
		///<summary>
		///   Takes the passed in string and appends it to the end of the current string
		///</summary>
		///<param type="string" name="sString">
		///   The string to use in bString converted to the correct encoding
		///</param>
		///<returns type="bString" />
		public function Append($sString) {
			
			//Makes sure that the string is UTF-8 encoded
			$this->sString .= mb_convert_encoding($sString, self::ENCODING);
			
			return $this;
		}
		
		///<summary>
		///   Provides a regularexpression match interface to the string
		///</summary>
		///<param type="string" name="sMatchExpression">
		///   The regular expression to match to
		///</param>
		///<returns type="bool">
		///   Whether the expresion was matched or not. The matched values are added to an internal
		///   array to be pulled from
		///</returns>
		public function Match($sMatchExpression) {
			$sMatchExpression = $sMatchExpression;
			
			$bMatch =mb_ereg_match($sMatchExpression, $this->sString, $this->aMatch);
			
			return !!$bMatch;
		}
		
		///<summary>
		///   Replaces one portion of a string with another
		///<summary>
		///<param type="array|string" name="mReplaceExpression">
		///   The string to replace within the current string, can be a regular expression or
		///   a simple string match. The default is regular expression
		///</param>
		///<param type="array|string" name="mWith" optional="true">
		///   What you replace the string with.
		///</param>
		///<returns type="bString" />
		public function Replace($mReplaceExpression, $mWith ='', $cType =self::REGULAR_EXPRESSION) {
			
			if($cType ==self::REGULAR_EXPRESSION) {
			
				$this->sString =mb_ereg_replace($mReplaceExpression, $mWith, $this->sString);
			} else {
				
				$this->sString =str_replace($mReplaceExpression, $mWith, $this->sString);
			}
			
			return $this;
		}
		
		///<summary>
		///   Strips certain tags from the string
		///</summary>
		///<param type="string" name="sTags" optional="true">
		///   The tags in a space delimited list
		///</param>
		///<returns type="bString" />
		public function StripTags($sTags ='') {
			
			$this->sString =strip_tags($this->sString, $sTags);
			
			return $this;
		}
		
		///<summary>
		///   The interface to the wordwrap function, for hard wraping of text
		///   at specific intervals
		///</summary>
		///<param type="int" name="nWidth" optional="true" default="75">
		///   The width of the text before the wraping
		///</param>
		///<param type="string" name="sBreak" optional="true">
		///   The character to use to break the line
		///</param>
		///<param type="bool" name="bCut" optional="true">
		///   The character to use to break long words, if true then long words are broken, if
		///   false then not.
		///</param>
		///<returns type="bString" />
		public function WordWrap($nWidth =75, $sBreak ="\n", $bCut =true) {
			
			$this->sString =wordwrap($this->sString, $nWidth, $sBreak, $cCut);
			
			return $this;
		}
		
		///<summary>
		///   The exact character at the suppied position
		///</summary>
		///<param type="int" name="nPosition">The position of the character</param>
		///<returns type="string">note: this is non-destructive</returns>
		public function CharacterAt($nPosition) {
			
			return $this->sString[$nPosition];
		}
		
		///<summary>
		///   The starting position of the supplied needle
		///</summary>
		///<param type="int" name="sNeedle">the string you woul like to find</param>
		///<param type="bitwise" name="...">Search from the end of the string to the begining</param>
		///<param type="int" name="...">Search from int character of the string</param>
		///<returns type="int"/>
		public function PositionOf($sNeedle) {
				$nOffset =0;
				$fStrpos ='mb_strpos';
				
				$aArgument =func_get_args();
				$sNeedle =array_shift($aArgument);
					
				foreach($aArgument as $mArgument) {
					if($mArgument ==self::REVERSE) {
						
						$fStrpos ='mb_strrpos';
					} elseif(is_numeric($mArgument)) {
						
						$nOffset =$mArgument;
					}
				}
				
				return $fStrpos($this->sString, $sNeedle, $nOffset);
		}
		
		///<summary>
		///   The string as chunked on a token.
		///</summary>
		///<returns type="array" />
		public function AsArray($sToken =' ') {
			
			return mb_split($sToken, $this->sString);
		}
		
		///<summary>
		///   The length of the string
		///</summary>
		///<returns type="int" />
		public function Length() {
			
			return mb_strlen($this->sString);
		}
		
		///<summary>
		///   Slices a string at a certain point
		///</summary>
		///<param type="int" name="nStart" optional="true">The start point of the slice</param>
		///<param type="int" name="nLength">The length of the string
		///<returns type="$this" />
		public function Slice($nStart =0, $nLength =null) {
			$this->sString =mb_strcut($this->sString, $nStart, $nLength, self::ENCODING);
			
			return $this;
		}
		
		///<summary>
		///   Checks to see if the string contians a string
		///</summary>
		///<returns type="bool" />
		public function Contains($mContains) {
			$mContainsExpression =$mContains;
			
			return mb_ereg_match($mContainsExpression, $this->sString);
		}
		
		///<summary>
		///   Encodes the string with HTML Hex entities but does not double encode &amp; &lt; and &gt;
		///</summary>
		///<returns type="$this" />
		public function XmlEncode() {
			$aXmlEntities =array('&lt;', '&amp;', '&gt;');
			$aXmlEntitiesKeeper =array('<', '&', '>');

			$this->sString =str_replace($aXmlEntities, $aXmlEntitiesKeeper, $this->sString);
			$this->sString =htmlentities($this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Decodes the string of HTML enties, but leaves the &amp; &lt; and &gt;
		///</summary>
		///<returns type="$this" />
		public function XmlDecode() {
			$aXmlEntities =array('&lt;', '&amp;', '&gt;');
			$aXmlEntitiesKeeper =array(md5($n =microtime(true)), md5($n+10), md5($n+20));
			
			$this->sString =str_replace($aXmlEntities, $aXmlEntitiesKeeper, $this->sString);
			$this->sString =html_entity_decode($this->sString);
			$this->sString =str_replace($aXmlEntitiesKeeper, $aXmlEntities, $this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Encodes the string with URL entities
		///</summary>
		///<returns type="$this" />
		public function UrlEncode() {
			$this->sString =urlencode($this->sString);

			return $this;
		}
	
		
		///<summary>
		///   Decodes the URL entities within the string
		///</summary>
		///<returns type="this" />
		public function UrlDecode() {
			$this->sString =urldecode($this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Encodes the string with HTML entities
		///</summary>
		///<returns type="this" />
		public function HtmlEncode() {
			$this->sString =htmlentities($this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Decodes HTML enities
		///</summary>
		///<returns type="this" />
		public function HtmlDecode() {
			$this->sString =html_entity_decode($this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Adds slashes to the front of '\ and " characters for DB
		///</summary>
		///<returns type="this" />
		public function AddSlashes() {
			$this->sString =addslashes($this->sString);
			return $this;
		}
		
		///<summary>
		///   Lowercases the string
		///</summary>
		///<returns type="this" />
		public function ToLower() {
			$this->sString = mb_strtolower($this->sString);
			
			return $this;
		}
		
		///<summary>
		///   Upercases the string
		///</summary>
		///<returns type="this" />
		public function ToUpper() {
			$this->sString = mb_strtoupper($this->sString);
			
			return $this;
		}
		
		
		///<summary>
		///   The string as a PHP scalar string
		///</summary>
		///<returns type="string" />
		public function __toString() {
			return $this->sString;
		}
	}

?>